//+------------------------------------------------------------------+
//|                                                           ma.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern int longMa = 20;
extern int shortMa = 10;
extern int callbackMa = 30;

extern int stop = 300;
extern int limit =900;
extern double lots = 1;
extern double trailingStop = 500;
extern int magic = 12345;
extern int goodK = 3;

//是否交叉
bool isCrossBuy = false;
bool isCrossSell = false;

//是否回调到支撑线
bool isBuyCallback = false;
bool isSellCallback = false;

//是否开仓
bool isBuyOpend =false;
bool isSellOpend = false;

datetime buytime = 0;
datetime selltime =0;

void OnTick()
  {
      //   lots = MathFloor((AccountBalance()/10000));
        //获取所有均线价格，包括长期，短期，回调
        double longmaprice1 = iMA(NULL,0,longMa,0,MODE_SMA,PRICE_CLOSE,1);
        double longmaprice2 = iMA(NULL,0,longMa,0,MODE_SMA,PRICE_CLOSE,2);
        double shortmaprice1 = iMA(NULL,0,shortMa,0,MODE_SMA,PRICE_CLOSE,1);
        double shortmaprice2 = iMA(NULL,0,shortMa,0,MODE_SMA,PRICE_CLOSE,2);
        double callbackprice = iMA(NULL,0,callbackMa,0,MODE_SMA,PRICE_CLOSE,0);
   
      // 均线交叉多头
      if(shortmaprice1>longmaprice1 && shortmaprice2<longmaprice2)
      {
         isCrossBuy = true;
         isCrossSell = false;
         isSellOpend = false;
         isSellCallback = false;
         closesell(Symbol()+"sell",magic);
      }
      
      // 均线交叉空头
      if(shortmaprice1<longmaprice1 && shortmaprice2>longmaprice2)
      {
         isCrossBuy = false;
         isCrossSell = true;
         isBuyOpend = false;
         isBuyCallback = false;
         closebuy(Symbol()+"buy",magic);
      }
      
      double lowPrice = Low[0];
      double highPrice = High[0];
      double openPrice = Open[0];
      double closePrice = Close[0];
      
      double lowPrice1 = Low[1];
      double highPrice1 = High[1];
      double openPrice1 = Open[1];
      double closePrice1 = Close[1];
      
      //下影线是上影线的2倍，然后实体是下影线的2倍    
      bool isGoodbuyK = goodK*(highPrice1 - closePrice1)<openPrice1-lowPrice1 && (closePrice1-openPrice1)>goodK*(openPrice1-lowPrice1);
      if(!isBuyOpend && isCrossBuy && lowPrice < callbackprice &&isGoodbuyK)
      {
         //符合下多的条件
         //第一个问题：一直下单
         //第二个问题：一次交叉里面，只希望做一单
         //解决当前这根K线，重复下单的问题
         if(buytime!=Time[0])
         {
            if(buy(lots,stop,limit,Symbol()+"buy",magic))
            {
               buytime = Time[0];
               isBuyOpend = true;
            }
            
         }
      }
      
      bool isGoodSellK = (highPrice1 - openPrice1)>goodK*(closePrice1-lowPrice1) && (openPrice1-closePrice1) > goodK*(highPrice1-openPrice1);
      if(!isSellOpend && isCrossSell && highPrice>callbackprice && isGoodSellK)
      {
         if(selltime!=Time[0])
         {
            if(sell(lots,stop,limit,Symbol()+"sell",magic))
            {
               selltime = Time[0];
               isSellOpend = true;
            }
            
         }
      }
      
      yidongzhisun();
  }

//下单函数，针对一个单子的
int buy(double lots,double sl,double tp,string comm,int buymagic)
{
   int returnTicket = 0;
   bool zhaodan = false;
   for(int i=0;i<OrdersTotal();i++)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         string zhushi = OrderComment();
         int magicNumber = OrderMagicNumber();
         if(OrderSymbol()==Symbol() && OrderType() == OP_BUY && zhushi==comm && magicNumber==buymagic)
         {
            zhaodan=true;
            break;
         }
      }
   }
   
   if(zhaodan==false)
   {
      if(sl!=0 && tp==0)
      {
         returnTicket = OrderSend(Symbol(),OP_BUY,lots,Ask,50,Ask-sl*Point,0,comm,buymagic,0,White);
      }
      if(sl==0 && tp!=0)
      {
         returnTicket = OrderSend(Symbol(),OP_BUY,lots,Ask,50,0,Ask+tp*Point,comm,buymagic,0,White);
      }
      if(sl==0 && tp==0)
      {
         returnTicket = OrderSend(Symbol(),OP_BUY,lots,Ask,50,0,0,comm,buymagic,0,White);
      }
      if(sl!=0 && tp!=0)
      {
         returnTicket = OrderSend(Symbol(),OP_BUY,lots,Ask,50,Ask-sl*Point,Ask+tp*Point,comm,buymagic,0,White);
      }
   }
   return(returnTicket);
}

int sell(double lots,double sl,double tp,string comm,int sellmagic)
{
   int returnTicket = 0;
   bool zhaodan = false;
   for(int i=0;i<OrdersTotal();i++)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         string zhushi = OrderComment();
         int magicNumber = OrderMagicNumber();
         if(OrderSymbol()==Symbol() && OrderType() == OP_SELL && zhushi==comm && magicNumber==sellmagic)
         {
            zhaodan=true;
            break;
         }
      }
   }
   
   if(zhaodan==false)
   {
      if(sl!=0 && tp==0)
      {
         returnTicket = OrderSend(Symbol(),OP_SELL,lots,Bid,50,Bid+sl*Point,0,comm,sellmagic,0,White);
      }
      if(sl==0 && tp!=0)
      {
         returnTicket = OrderSend(Symbol(),OP_SELL,lots,Bid,50,0,Bid-tp*Point,comm,sellmagic,0,White);
      }
      if(sl==0 && tp==0)
      {
         returnTicket = OrderSend(Symbol(),OP_SELL,lots,Bid,50,0,0,comm,sellmagic,0,White);
      }
      if(sl!=0 && tp!=0)
      {
         returnTicket = OrderSend(Symbol(),OP_SELL,lots,Bid,50,Bid+sl*Point,Bid-tp*Point,comm,sellmagic,0,White);
      }
   }
   return(returnTicket);
}

//平一个货币，同一个方向的单子，因为本系统一个货币，一个方向，只会有一个单子存在
void closebuy(string comm,int magic)
{
   int t = OrdersTotal();
   for(int i=t-1;i>=0;i--)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         if(OrderSymbol()==Symbol() && OrderType()==OP_BUY && OrderComment()==comm && OrderMagicNumber() == magic)
         {
            OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),300,Green);
         }
      }
   }   
}

void closesell(string comm,int magic)
{
   int t = OrdersTotal();
   for(int i=t-1;i>=0;i--)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         if(OrderSymbol()==Symbol() && OrderType()==OP_SELL && OrderComment()==comm && OrderMagicNumber() == magic)
         {
            OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),300,Green);
         }
      }
   }   
}

//设置移动止损
void yidongzhisun()
{
   for(int i=0;i<OrdersTotal();i++)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true)
      {
         if(OrderType()==OP_BUY && OrderSymbol()==Symbol() && OrderMagicNumber()==magic)
         {
            if((Bid-OrderOpenPrice())>=Point*trailingStop)
            {
               if(OrderStopLoss()<(Bid-Point*trailingStop) || (OrderStopLoss()==0))
               {
                  OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*trailingStop,OrderTakeProfit(),0,Green);
               }
            }
         }
         
         if(OrderType()==OP_SELL && OrderSymbol()==Symbol() && OrderMagicNumber()==magic)
         {
            if((OrderOpenPrice()-Ask)>=Point*trailingStop)
            {
               if(OrderStopLoss()>(Ask+Point*trailingStop) || (OrderStopLoss()==0))
               {
                  OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*trailingStop,OrderTakeProfit(),0,Green);
               }
            }
         }
      }
   }
}


int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
